/*
 * File:   UserDelay.c
 * Author: Honrun
 */

#include "n32g031.h"
#include "stdint.h"
#include "DevicesTime.h"
#include "DevicesDelay.h"


/*
 * Return:      void
 * Parameters:  void
 * Description: SysTick初始化
 */
void vSysTickDelayInit(void)
{
    /* Set the SysTick Counter Load */
    SysTick->LOAD = SysTick_LOAD_RELOAD_Msk - 1;
    /* Load the SysTick Counter Value */
    SysTick->VAL = 0;
    /* ENABLE */
    SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
}

/*
 * Return:      void
 * Parameters:  Time: 延时时间
 * Description: 秒延时
 */
void vSysTickDelayS(float fTime)
{
    int32_t iTime = fTime;

    while((iTime--) > 0)
    {
        vSysTickDelayMs(1000.0f);
    }

    fTime -= iTime;
    vSysTickDelayMs(fTime);
}

/*
 * Return:      void
 * Parameters:  Time: 延时时间
 * Description: 毫秒延时
 */
void vSysTickDelayMs(float fTime)
{
    int32_t iTime = fTime / 100.0f;

    while((iTime--) > 0)
    {
        vSysTickDelayUs(100.0f);
    }

    fTime -= iTime * 100;
    vSysTickDelayUs(fTime);
}

/*
 * Return:      void
 * Parameters:  Time: 延时时间
 * Description: 微秒延时
 */
void vSysTickDelayUs(float fTime)
{
    volatile uint32_t uiTimeStop = 0u, uiTimeStart = 0;

    if(fTime < 0.1f)
        return;

    uiTimeStart = ((SysTick_LOAD_RELOAD_Msk - 1) - SysTick->VAL);
    uiTimeStop  = (uint32_t)((SystemCoreClock / 1000000u) * fTime + uiTimeStart);
    /* 24bit溢出处理 */
    uiTimeStop &= SysTick_LOAD_RELOAD_Msk - 1;

    if(uiTimeStop >= uiTimeStart)
        while((((SysTick_LOAD_RELOAD_Msk - 1) - SysTick->VAL) > uiTimeStart) && (((SysTick_LOAD_RELOAD_Msk - 1) - SysTick->VAL) < uiTimeStop));
    else
        while(!((((SysTick_LOAD_RELOAD_Msk - 1) - SysTick->VAL) > uiTimeStop) && (((SysTick_LOAD_RELOAD_Msk - 1) - SysTick->VAL) < uiTimeStart)));
}

/*
 * Return:      void
 * Parameters:  void
 * Description: DWT初始化
 */
void vTimerDelayInit(void)
{
}

/*
 * Return:      void
 * Parameters:  Time: 延时时间
 * Description: 秒延时
 */
void vTimerDelayS(float fTime)
{
    vTimerDelayUs(fTime * 1000000.0f);
}

/*
 * Return:      void
 * Parameters:  Time: 延时时间
 * Description: 毫秒延时
 */
void vTimerDelayMs(float fTime)
{
    vTimerDelayUs(fTime * 1000.0f);
}

/*
 * Return:      void
 * Parameters:  Time: 延时时间
 * Description: 微秒延时
 */
void vTimerDelayUs(float fTime)
{
    volatile int64_t uiTimeStop = 0u, uiTimeStart = 0;

    if(fTime < 1.0f)
        return;

    uiTimeStart = lTimeGetStamp();
    uiTimeStop = uiTimeStart + fTime;

    while(lTimeGetStamp() < uiTimeStop);
}
